{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.0.0-alpha0\n",
      "sys.version_info(major=3, minor=7, micro=3, releaselevel='final', serial=0)\n",
      "matplotlib 3.0.3\n",
      "numpy 1.16.2\n",
      "pandas 0.24.2\n",
      "sklearn 0.20.3\n",
      "tensorflow 2.0.0-alpha0\n",
      "tensorflow.python.keras.api._v2.keras 2.2.4-tf\n"
     ]
    }
   ],
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import time\n",
    "import tensorflow as tf\n",
    "\n",
    "from tensorflow import keras\n",
    "\n",
    "print(tf.__version__)\n",
    "print(sys.version_info)\n",
    "for module in mpl, np, pd, sklearn, tf, keras:\n",
    "    print(module.__name__, module.__version__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   survived     sex   age  n_siblings_spouses  parch     fare  class     deck  \\\n",
      "0         0    male  22.0                   1      0   7.2500  Third  unknown   \n",
      "1         1  female  38.0                   1      0  71.2833  First        C   \n",
      "2         1  female  26.0                   0      0   7.9250  Third  unknown   \n",
      "3         1  female  35.0                   1      0  53.1000  First        C   \n",
      "4         0    male  28.0                   0      0   8.4583  Third  unknown   \n",
      "\n",
      "   embark_town alone  \n",
      "0  Southampton     n  \n",
      "1    Cherbourg     n  \n",
      "2  Southampton     y  \n",
      "3  Southampton     n  \n",
      "4   Queenstown     y  \n",
      "   survived     sex   age  n_siblings_spouses  parch     fare   class  \\\n",
      "0         0    male  35.0                   0      0   8.0500   Third   \n",
      "1         0    male  54.0                   0      0  51.8625   First   \n",
      "2         1  female  58.0                   0      0  26.5500   First   \n",
      "3         1  female  55.0                   0      0  16.0000  Second   \n",
      "4         1    male  34.0                   0      0  13.0000  Second   \n",
      "\n",
      "      deck  embark_town alone  \n",
      "0  unknown  Southampton     y  \n",
      "1        E  Southampton     y  \n",
      "2        C  Southampton     y  \n",
      "3  unknown  Southampton     y  \n",
      "4        D  Southampton     y  \n"
     ]
    }
   ],
   "source": [
    "# https://storage.googleapis.com/tf-datasets/titanic/train.csv\n",
    "# https://storage.googleapis.com/tf-datasets/titanic/eval.csv\n",
    "train_file = \"./data/titanic/train.csv\"\n",
    "eval_file = \"./data/titanic/eval.csv\"\n",
    "\n",
    "train_df = pd.read_csv(train_file)\n",
    "eval_df = pd.read_csv(eval_file)\n",
    "\n",
    "print(train_df.head())\n",
    "print(eval_df.head())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "      sex   age  n_siblings_spouses  parch     fare  class     deck  \\\n",
      "0    male  22.0                   1      0   7.2500  Third  unknown   \n",
      "1  female  38.0                   1      0  71.2833  First        C   \n",
      "2  female  26.0                   0      0   7.9250  Third  unknown   \n",
      "3  female  35.0                   1      0  53.1000  First        C   \n",
      "4    male  28.0                   0      0   8.4583  Third  unknown   \n",
      "\n",
      "   embark_town alone  \n",
      "0  Southampton     n  \n",
      "1    Cherbourg     n  \n",
      "2  Southampton     y  \n",
      "3  Southampton     n  \n",
      "4   Queenstown     y  \n",
      "      sex   age  n_siblings_spouses  parch     fare   class     deck  \\\n",
      "0    male  35.0                   0      0   8.0500   Third  unknown   \n",
      "1    male  54.0                   0      0  51.8625   First        E   \n",
      "2  female  58.0                   0      0  26.5500   First        C   \n",
      "3  female  55.0                   0      0  16.0000  Second  unknown   \n",
      "4    male  34.0                   0      0  13.0000  Second        D   \n",
      "\n",
      "   embark_town alone  \n",
      "0  Southampton     y  \n",
      "1  Southampton     y  \n",
      "2  Southampton     y  \n",
      "3  Southampton     y  \n",
      "4  Southampton     y  \n",
      "0    0\n",
      "1    1\n",
      "2    1\n",
      "3    1\n",
      "4    0\n",
      "Name: survived, dtype: int64\n",
      "0    0\n",
      "1    0\n",
      "2    1\n",
      "3    1\n",
      "4    1\n",
      "Name: survived, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "y_train = train_df.pop('survived')\n",
    "y_eval = eval_df.pop('survived')\n",
    "\n",
    "print(train_df.head())\n",
    "print(eval_df.head())\n",
    "print(y_train.head())\n",
    "print(y_eval.head())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>age</th>\n",
       "      <th>n_siblings_spouses</th>\n",
       "      <th>parch</th>\n",
       "      <th>fare</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>627.000000</td>\n",
       "      <td>627.000000</td>\n",
       "      <td>627.000000</td>\n",
       "      <td>627.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>29.631308</td>\n",
       "      <td>0.545455</td>\n",
       "      <td>0.379585</td>\n",
       "      <td>34.385399</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>12.511818</td>\n",
       "      <td>1.151090</td>\n",
       "      <td>0.792999</td>\n",
       "      <td>54.597730</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>0.750000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>23.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>7.895800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>28.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>15.045800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>35.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>31.387500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>80.000000</td>\n",
       "      <td>8.000000</td>\n",
       "      <td>5.000000</td>\n",
       "      <td>512.329200</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              age  n_siblings_spouses       parch        fare\n",
       "count  627.000000          627.000000  627.000000  627.000000\n",
       "mean    29.631308            0.545455    0.379585   34.385399\n",
       "std     12.511818            1.151090    0.792999   54.597730\n",
       "min      0.750000            0.000000    0.000000    0.000000\n",
       "25%     23.000000            0.000000    0.000000    7.895800\n",
       "50%     28.000000            0.000000    0.000000   15.045800\n",
       "75%     35.000000            1.000000    0.000000   31.387500\n",
       "max     80.000000            8.000000    5.000000  512.329200"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_df.describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sex ['male' 'female']\n",
      "n_siblings_spouses [1 0 3 4 2 5 8]\n",
      "parch [0 1 2 5 3 4]\n",
      "class ['Third' 'First' 'Second']\n",
      "deck ['unknown' 'C' 'G' 'A' 'B' 'D' 'F' 'E']\n",
      "embark_town ['Southampton' 'Cherbourg' 'Queenstown' 'unknown']\n",
      "alone ['n' 'y']\n"
     ]
    }
   ],
   "source": [
    "categorical_columns = ['sex', 'n_siblings_spouses', 'parch', 'class',\n",
    "                       'deck', 'embark_town', 'alone']\n",
    "numeric_columns = ['age', 'fare']\n",
    "\n",
    "feature_columns = []\n",
    "for categorical_column in categorical_columns:\n",
    "    vocab = train_df[categorical_column].unique()\n",
    "    print(categorical_column, vocab)\n",
    "    feature_columns.append(\n",
    "        tf.feature_column.indicator_column(\n",
    "            tf.feature_column.categorical_column_with_vocabulary_list(\n",
    "                categorical_column, vocab)))\n",
    "\n",
    "for categorical_column in numeric_columns:\n",
    "    feature_columns.append(\n",
    "        tf.feature_column.numeric_column(\n",
    "            categorical_column, dtype=tf.float32))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def make_dataset(data_df, label_df, epochs = 10, shuffle = True,\n",
    "                 batch_size = 32):\n",
    "    dataset = tf.data.Dataset.from_tensor_slices(\n",
    "        (dict(data_df), label_df))\n",
    "    if shuffle:\n",
    "        dataset = dataset.shuffle(10000)\n",
    "    dataset = dataset.repeat(epochs).batch(batch_size)\n",
    "    return dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING: Logging before flag parsing goes to stderr.\n",
      "W0612 21:35:53.951065 140736297124800 deprecation.py:323] From /Users/zhangyx/workspace/environments/tf2_py3/lib/python3.7/site-packages/tensorflow/python/training/training_util.py:238: Variable.initialized_value (from tensorflow.python.ops.variables) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use Variable.read_value. Variables in 2.X are initialized automatically both in eager and graph (inside tf.defun) contexts.\n",
      "W0612 21:35:54.124486 140736297124800 deprecation.py:506] From /Users/zhangyx/workspace/environments/tf2_py3/lib/python3.7/site-packages/tensorflow/python/ops/variable_scope.py:883: calling Zeros.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Call initializer instance with the dtype argument instead of passing it to the constructor\n",
      "W0612 21:35:54.217702 140736297124800 deprecation.py:323] From /Users/zhangyx/workspace/environments/tf2_py3/lib/python3.7/site-packages/tensorflow_estimator/python/estimator/head/base_head.py:546: to_float (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use `tf.cast` instead.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<tensorflow_estimator.python.estimator.canned.baseline.BaselineClassifierV2 at 0x130ae80b8>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "output_dir = 'baseline_model'\n",
    "if not os.path.exists(output_dir):\n",
    "    os.mkdir(output_dir)\n",
    "\n",
    "baseline_estimator = tf.estimator.BaselineClassifier(\n",
    "    model_dir = output_dir,\n",
    "    n_classes = 2)\n",
    "baseline_estimator.train(input_fn = lambda : make_dataset(\n",
    "    train_df, y_train, epochs = 100))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "W0612 21:36:00.546827 140736297124800 deprecation.py:323] From /Users/zhangyx/workspace/environments/tf2_py3/lib/python3.7/site-packages/tensorflow/python/training/saver.py:1276: checkpoint_exists (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use standard file APIs to check for files with this prefix.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'accuracy': 0.625,\n",
       " 'accuracy_baseline': 0.625,\n",
       " 'auc': 0.5,\n",
       " 'auc_precision_recall': 0.375,\n",
       " 'average_loss': 0.66189873,\n",
       " 'label/mean': 0.375,\n",
       " 'loss': 0.6586314,\n",
       " 'precision': 0.0,\n",
       " 'prediction/mean': 0.387595,\n",
       " 'recall': 0.0,\n",
       " 'global_step': 1960}"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "baseline_estimator.evaluate(input_fn = lambda : make_dataset(\n",
    "    eval_df, y_eval, epochs = 1, shuffle = False, batch_size = 20))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "W0612 21:36:01.847284 140736297124800 deprecation.py:323] From /Users/zhangyx/workspace/environments/tf2_py3/lib/python3.7/site-packages/tensorflow/python/ops/lookup_ops.py:1347: to_int64 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use `tf.cast` instead.\n",
      "W0612 21:36:01.864803 140736297124800 deprecation.py:323] From /Users/zhangyx/workspace/environments/tf2_py3/lib/python3.7/site-packages/tensorflow/python/feature_column/feature_column_v2.py:4307: IndicatorColumn._variable_shape (from tensorflow.python.feature_column.feature_column_v2) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "The old _FeatureColumn APIs are being deprecated. Please use the new FeatureColumn APIs instead.\n",
      "W0612 21:36:01.866600 140736297124800 deprecation.py:323] From /Users/zhangyx/workspace/environments/tf2_py3/lib/python3.7/site-packages/tensorflow/python/feature_column/feature_column_v2.py:4362: VocabularyListCategoricalColumn._num_buckets (from tensorflow.python.feature_column.feature_column_v2) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "The old _FeatureColumn APIs are being deprecated. Please use the new FeatureColumn APIs instead.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<tensorflow_estimator.python.estimator.canned.linear.LinearClassifierV2 at 0x13142cd30>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linear_output_dir = 'linear_model'\n",
    "if not os.path.exists(linear_output_dir):\n",
    "    os.mkdir(linear_output_dir)\n",
    "linear_estimator = tf.estimator.LinearClassifier(\n",
    "    model_dir = linear_output_dir,\n",
    "    n_classes = 2,\n",
    "    feature_columns = feature_columns)\n",
    "linear_estimator.train(input_fn = lambda : make_dataset(\n",
    "    train_df, y_train, epochs = 100))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'accuracy': 0.77272725,\n",
       " 'accuracy_baseline': 0.625,\n",
       " 'auc': 0.83694524,\n",
       " 'auc_precision_recall': 0.7895812,\n",
       " 'average_loss': 0.4830001,\n",
       " 'label/mean': 0.375,\n",
       " 'loss': 0.46644244,\n",
       " 'precision': 0.6788991,\n",
       " 'prediction/mean': 0.4332884,\n",
       " 'recall': 0.74747473,\n",
       " 'global_step': 1960}"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linear_estimator.evaluate(input_fn = lambda : make_dataset(\n",
    "    eval_df, y_eval, epochs = 1, shuffle = False))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "W0612 21:36:15.209811 140736297124800 deprecation.py:506] From /Users/zhangyx/workspace/environments/tf2_py3/lib/python3.7/site-packages/tensorflow/python/ops/init_ops.py:1257: calling VarianceScaling.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Call initializer instance with the dtype argument instead of passing it to the constructor\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<tensorflow_estimator.python.estimator.canned.dnn.DNNClassifierV2 at 0x133d09898>"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dnn_output_dir = './dnn_model'\n",
    "if not os.path.exists(dnn_output_dir):\n",
    "    os.mkdir(dnn_output_dir)\n",
    "dnn_estimator = tf.estimator.DNNClassifier(\n",
    "    model_dir = dnn_output_dir,\n",
    "    n_classes = 2,\n",
    "    feature_columns=feature_columns,\n",
    "    hidden_units = [128, 128],\n",
    "    activation_fn = tf.nn.relu,\n",
    "    optimizer = 'Adam')\n",
    "dnn_estimator.train(input_fn = lambda : make_dataset(\n",
    "    train_df, y_train, epochs = 100))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'accuracy': 0.79545456,\n",
       " 'accuracy_baseline': 0.625,\n",
       " 'auc': 0.84817874,\n",
       " 'auc_precision_recall': 0.8123316,\n",
       " 'average_loss': 0.525522,\n",
       " 'label/mean': 0.375,\n",
       " 'loss': 0.50615704,\n",
       " 'precision': 0.6956522,\n",
       " 'prediction/mean': 0.43443263,\n",
       " 'recall': 0.8080808,\n",
       " 'global_step': 1960}"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dnn_estimator.evaluate(input_fn = lambda : make_dataset(\n",
    "    eval_df, y_eval, epochs = 1, shuffle = False))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
